package com.wf.smartcomm.server.serviceImpl;

import java.util.List;

import javax.annotation.Resource;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.wf.smartcomm.server.bean.UnLock;
import com.wf.smartcomm.server.bean.User;
import com.wf.smartcomm.server.bean.Village;
import com.wf.smartcomm.server.model.Page;
import com.wf.smartcomm.server.service.UserService;
import com.wf.smartcomm.server.util.ConstantUtils;
import com.wf.smartcomm.server.util.IdUtils;
import com.wf.smartcomm.server.util.StringUtil;

/** 
 * @author 38884306@qq.com  
 * @version 创建时间：2015-5-19 下午1:35:57 
 * 
 */
@Service
@Transactional
public class UserServiceImpl implements UserService {

	@Resource
	private SessionFactory factory;
	
	@Override
	@Transactional(propagation=Propagation.SUPPORTS)
	public void registe(User user) {
		 factory.getCurrentSession().persist(user);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public User login(User user) {
		Query query = factory.getCurrentSession().createQuery("from User user where user.username = binary(:username) and user.password = binary(:password) and user.isUnReg = 0");
		query.setParameter("username", user.getUsername());
		query.setParameter("password", user.getPassword());
		return (User) query.uniqueResult();
	}

	@Override
	public void unlock(UnLock unlock) {
		unlock.setObjectId(IdUtils.uuid());
		unlock.setCreatedAt(String.valueOf(System.currentTimeMillis()));
		factory.getCurrentSession().persist(unlock);
	}
	
	@Override
	public void updateInfo(User user) {
		user.setUpdateAt(String.valueOf(System.currentTimeMillis()));
		factory.getCurrentSession().update(user);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public User getUserByUsername(String username) {
		Query query = factory.getCurrentSession().createQuery("from User user where user.username = binary(:username) and user.isUnReg = 0");
		query.setParameter("username", username);
		return (User) query.uniqueResult();
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public User getUserById(String objectId) {
		Query query = factory.getCurrentSession().createQuery("from User user where user.objectId = :objectId and user.isUnReg = 0");
		query.setParameter("objectId", objectId);
		return (User) query.uniqueResult();
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void getAttachUser(User user,Page page) {
		Query query = factory.getCurrentSession().createQuery("from User where parent =:parent and type != 4 and isUnReg = 0 order by createdAt");
		query.setParameter("parent", user);
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listByHouse(String houseId,Page page) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_user where objectId in (select uid from t_user_relation_house where hid =:houseId) and isUnReg = 0").addEntity(User.class);
		query.setParameter("houseId", houseId);
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation =Propagation.NOT_SUPPORTED)
	public void queryByPage(Village village,Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from User where loginVillage =:village and type = 1 and isUnReg = 0");
		query.setParameter("village", village);
		Long count = (Long) query.uniqueResult();
		page.setTotalCount(count.intValue());
		query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and type = 1 and isUnReg = 0");
		query.setParameter("village", village);
		if (page.getPageSize() != -1) {
			query.setFirstResult(page.getBeginIndex());
			query.setMaxResults(page.getPageSize());
		}
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void queryPrimaryByKey(Village village,String key,Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from User where type = 1 and loginVillage =:village and (name like :key or username like :key) and isUnReg = 0");
		query.setParameter("village", village);
		query.setParameter("key", "%"+key+"%");
		Long counts = (Long)query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from User where type = 1 and loginVillage =:village and (name like :key or username like :key) and isUnReg = 0");
		query.setParameter("village", village);
		query.setParameter("key", "%"+key+"%");
		if (page.getPageSize() != -1) {
			query.setFirstResult(page.getBeginIndex());
			query.setMaxResults(page.getPageSize());
		}
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listAttach(Village village,String hostId, Page page) {
		if (!StringUtil.isEmpty(hostId)) {
			User user = new User();
			user.setObjectId(hostId);
			Query query = factory.getCurrentSession().createQuery("select count(*) from User where loginVillage =:village and parent=:host and isUnReg = 0");
			query.setParameter("host", user);
			query.setParameter("village", village);
			Long counts = (Long)query.uniqueResult();
			page.setTotalCount(counts.intValue());
			query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and parent=:host and isUnReg = 0");
			query.setParameter("host", user);
			query.setParameter("village", village);
			if (page.getPageSize() != -1) {
				query.setFirstResult(page.getBeginIndex());
				query.setMaxResults(page.getPageSize());
			}
			page.setDataList(query.list());
		}else {
			Query query = factory.getCurrentSession().createQuery("select count(*) from User where loginVillage =:village and type = 2 and isUnReg = 0");
			query.setParameter("village", village);
			Long count = (Long) query.uniqueResult();
			page.setTotalCount(count.intValue());
			query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and type = 2 and isUnReg = 0");
			query.setParameter("village", village);
			if (page.getPageSize() != -1) {
				query.setFirstResult(page.getBeginIndex());
				query.setMaxResults(page.getPageSize());
			}
			page.setDataList(query.list());
		}
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listUm(Village village,Page page) {
		Query query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and type = 0 and isUnReg = 0");
		query.setParameter("village", village);
		page.setDataList(query.list());
	}

	@Override
	public void setType(User user,String type) {
		Query query = factory.getCurrentSession().createSQLQuery("update t_user set type =:type where objectId =:id");
		query.setParameter("type", type);
		query.setParameter("id", user.getObjectId());
		query.executeUpdate();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listProperty(Village loginVillage, Page page) {
		if (loginVillage == null) {
			Query query = factory.getCurrentSession().createQuery("select count(*) from User where type = 3 and isUnReg = 0");
			Long counts = (Long) query.uniqueResult();
			page.setTotalCount(counts.intValue());
			if (page.getTotalCount() > 0) {
				query = factory.getCurrentSession().createQuery("from User where type = 3 and isUnReg = 0");
				query.setFirstResult(page.getBeginIndex());
				query.setMaxResults(page.getPageSize());
				page.setDataList(query.list());
			}
			return;
		}
		Query query = factory.getCurrentSession().createQuery("select count(*) from User where loginVillage =:village and type = 3 and isUnReg = 0");
		query.setParameter("village", loginVillage);
		Long counts = (Long) query.uniqueResult();
		page.setTotalCount(counts.intValue());
		if (page.getTotalCount() > 0) {
			query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and type = 3 and isUnReg = 0");
			query.setParameter("village", loginVillage);
			query.setFirstResult(page.getBeginIndex());
			query.setMaxResults(page.getPageSize());
			page.setDataList(query.list());
		}
	}

	@Override
	public void setVillage(User user, String vid) {
		String sql = "update t_user set vid =:vid where objectId =:uid";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("vid", vid);
		query.setParameter("uid", user.getObjectId());
		query.executeUpdate();
	}

	@Override
	public void update(User user) {
		user.setUpdateAt(String.valueOf(System.currentTimeMillis()));
		factory.getCurrentSession().update(user);
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listUmUser(String hid,Page page) {
		String sql = "select uid from t_unitMachine where objectId in (select mid from t_machine_relation_house where hid =:hid)";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("hid", hid);
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void list(Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from User where type = 3 and isUnReg = 0");
		Long counts = (Long) query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from User where type = 3 and isUnReg = 0");
		query.setFirstResult(page.getBeginIndex());
		query.setMaxResults(page.getPageSize());
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listByVillage(Village village, Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from User where loginVillage =:village and isUnReg = 0 and type != 0");
		query.setParameter("village", village);
		Long counts = (Long) query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and isUnReg = 0 and type != 0");
		query.setParameter("village", village);
		page.setDataList(query.list());
	}
	
	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listAllByVillage(Village village, Page page) {
		Query query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and type in (1,2,3) and isUnReg = 0 and deviceType = 0");
		query.setParameter("village", village);
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listUmUser(Page page) {
		String hql = "from User where type = 0 and isUnReg = 0";
		Query query = factory.getCurrentSession().createQuery(hql);
		page.setDataList(query.list());
	}

	@Override
	public void deleteUser(User user) {
		Query query = factory.getCurrentSession().createQuery("update User set isUnReg = 1 where objectId =:id");
		query.setParameter("id", user.getObjectId());
		query.executeUpdate();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void queryAttachByKey(Village village, String key, Page page) {
		Query query = factory.getCurrentSession().createQuery("select count(*) from User where type = 2 and loginVillage =:village and (name like :key or username like :key) and isUnReg = 0");
		query.setParameter("village", village);
		query.setParameter("key", "%"+key+"%");
		Long counts = (Long)query.uniqueResult();
		page.setTotalCount(counts.intValue());
		query = factory.getCurrentSession().createQuery("from User where type = 2 and loginVillage =:village and (name like :key or username like :key) and isUnReg = 0");
		query.setParameter("village", village);
		query.setParameter("key", "%"+key+"%");
		query.setFirstResult(page.getBeginIndex());
		query.setMaxResults(page.getPageSize());
		page.setDataList(query.list());
	}

	@Override
	public void addVillage(User user, Village village) {
		String sql = "insert into t_user_relation_village (uid,vid) values(:uid,:vid)";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("uid", user.getObjectId());
		query.setParameter("vid", village.getObjectId());
		query.executeUpdate();
	}

	@Override
	public void deleteUmUser(User user) {
		factory.getCurrentSession().delete(user);
	}

	@Override
	public void logout(User user) {
		factory.getCurrentSession().update(user);
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void counts(Village loginVillage, Page page) {
		if (loginVillage != null) {
			String hql = "select count(*) from User where loginVillage =:village";
			Query query = factory.getCurrentSession().createQuery(hql);
			query.setParameter("village", loginVillage);
			Long counts = (Long) query.uniqueResult();
			page.setTotalCount(counts.intValue());
			return;
		}
		
		String hql = "select count(*) from User";
		Query query = factory.getCurrentSession().createQuery(hql);
		Long counts = (Long) query.uniqueResult();
		page.setTotalCount(counts.intValue());
	}

	@Override
	public void realDel(User user) {
		factory.getCurrentSession().delete(user);
	}

	@Override
	public void initVoipInfo(User user) {
		String sql = "update t_user set subAccountSid =:subAccountSid,voipAccount =:voipAccount,voipPwd =:voipPwd,subToken =:subToken where objectId =:userId";
		Query query = factory.getCurrentSession().createSQLQuery(sql);
		query.setParameter("subAccountSid", user.getSubAccountSid());
		query.setParameter("voipAccount", user.getVoipAccount());
		query.setParameter("voipPwd", user.getVoipPwd());
		query.setParameter("subToken", user.getSubToken());
		query.setParameter("userId", user.getObjectId());
		query.executeUpdate();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public User getUserByOpenId(String openId) {
		String hql = "from User where openId =:openId";
		Query query = factory.getCurrentSession().createQuery(hql);
		query.setParameter("openId", openId);
		return (User) query.uniqueResult();
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void searchByKey(String key, Page page) {
		Query query = factory.getCurrentSession().createQuery("from User where type = 5 and isUnReg = 0 and username like :key");
		query.setParameter("key", "%"+key+"%");
		query.setFirstResult(page.getBeginIndex());
		query.setMaxResults(page.getPageSize());
		page.setDataList(query.list());
	}

	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public void listAttachByHouse(String hid, Page page) {
		String sql = "select * from t_user where objectId in (select uid from t_user_relation_house where hid =:hid) and isUnReg = 0 order by priority";
		Query query = factory.getCurrentSession().createSQLQuery(sql).addEntity(User.class);
		query.setParameter("hid", hid);
		page.setDataList(query.list());
	}

	@Override
	public List<User> listToJobSchedule(Village village) {
		Query query = factory.getCurrentSession().createQuery("from User where loginVillage =:village and type = 1 and isUnReg = 0");
		query.setParameter("village", village);
		return query.list();
	}

	@Override
	public void listAll(Page page) {
		Query query =  factory.getCurrentSession().createQuery("from User where type in (1,2,3) and isUnReg = 0 and deviceType = 0");
		page.setDataList(query.list());
	}

	@Override
	public User getCenterUser(String vid) {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_user where vid =:vid and isCenterUser = 1").addEntity(User.class);
		query.setParameter("vid", vid);
		return (User) query.uniqueResult();
	}

	@Override
	public User getUserByVoip(String called) {
		Query query = factory.getCurrentSession().createQuery("from User where voipAccount = :called");
		query.setParameter("called", called);
		return (User) query.uniqueResult();
	}

	@Override
	public void listCenterByVillage(Village village) {
		
	}

	@Override
	public List<User> listAllCenter() {
		Query query = factory.getCurrentSession().createSQLQuery("select * from t_user where isCenterUser = 1").addEntity(User.class);
		return query.list();
	}
}
